home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C++ / Snippets / QD3D Juggler / Juggler Sources / CQD3DPane.cp < prev    next >
Encoding:
Text File  |  1995-12-27  |  5.4 KB  |  195 lines  |  [TEXT/CWIE]

  1. //
  2. //    CQD3DPane.cp
  3. //
  4. //    class CQD3DPane [abstract]
  5. //    A Pane for rendering a QuickDraw 3D view.
  6. //
  7. //    by James Jennings
  8. //    November 21, 1995
  9. //
  10.  
  11. #include "CQD3DPane.h"
  12. #include "StQ3Disposer.h"
  13. #include "QD3D Debug Macros.h"
  14.  
  15. #include <QD3DGeometry.h>
  16. #include <QD3DShader.h>
  17. #include <QD3DCamera.h>
  18. #include <QD3DLight.h>
  19. #include <QD3DGroup.h>
  20. #include <QD3DRenderer.h>
  21. #include <QD3DDrawContext.h>
  22. #include <QD3DMath.h>
  23. #include <QD3DTransform.h>
  24. #include <QD3DAcceleration.h>    // defines kQAVendor_BestChoice
  25.  
  26. CQD3DPane::CQD3DPane()
  27.     : mView(0), mModel(0), mInterpolation(0), mBackFacing(0), mFillStyle(0)
  28. {    // default constructor
  29.     // Does nothing. Must call FinishCreate() later.
  30. }
  31.  
  32. CQD3DPane::CQD3DPane(const CQD3DPane &inOriginal) : LPane(inOriginal),
  33.     mView(0), mModel(0), mInterpolation(0), mBackFacing(0), mFillStyle(0)
  34. {    // copy constructor
  35.     mView             = ::Q3Object_Duplicate(inOriginal.mView);
  36.     ThrowIfNil_(mView);
  37.     mModel            = ::Q3Shared_GetReference(inOriginal.mModel);
  38.     mInterpolation    = ::Q3Shared_GetReference(inOriginal.mInterpolation);
  39.     mBackFacing        = ::Q3Shared_GetReference(inOriginal.mBackFacing);
  40.     mFillStyle         = ::Q3Shared_GetReference(inOriginal.mFillStyle);
  41. }
  42.     
  43. CQD3DPane::CQD3DPane(LStream *inStream)    : LPane(inStream),
  44.     mView(0), mModel(0), mInterpolation(0), mBackFacing(0), mFillStyle(0)
  45. {    // stream constructor
  46.     // Does nothing. Must call FinishCreate() later.
  47. }
  48.     
  49. CQD3DPane::~CQD3DPane()
  50. {    // destructor
  51.     if (mFillStyle) ::Q3Object_Dispose(mFillStyle);
  52.     mFillStyle = 0;
  53.     if (mBackFacing) ::Q3Object_Dispose(mBackFacing);
  54.     mBackFacing = 0;
  55.     if (mInterpolation) ::Q3Object_Dispose(mInterpolation);
  56.     mInterpolation = 0;
  57.     if (mModel) ::Q3Object_Dispose(mModel);
  58.     mModel = 0;
  59.     if (mView) ::Q3Object_Dispose(mView);
  60.     mView = 0;
  61. }
  62.  
  63. void
  64. CQD3DPane::FinishCreateSelf()
  65. {    // We want to be able to override the helper methods, so we can't
  66.     // put this stuff in the constructor.
  67.     // This method creates a view, and adds the minimum required stuff.
  68.     // Since the copy constructor might set each member, we check for 0
  69.     // before creating each item.
  70.  
  71.     // Create view for QuickDraw 3D.
  72.     if (mView==0)
  73.         MakeView() ;
  74.     
  75.     // Create the main display group.
  76.     if (mModel==0)
  77.         MakeModel() ;
  78.     
  79.     // assorted styles
  80.     if (mInterpolation==0)
  81.         mInterpolation = ::Q3InterpolationStyle_New( GetInterpolationStyle() ) ;
  82.     if (mBackFacing==0)
  83.         mBackFacing = ::Q3BackfacingStyle_New( GetBackfacingStyle() ) ;
  84.     if (mFillStyle==0)
  85.         mFillStyle = ::Q3FillStyle_New( GetFillStyle() ) ;
  86. }
  87.  
  88. void
  89. CQD3DPane::MakeView()
  90. {    // A View must have a Camera, a Renderer, and a Draw Context.
  91.     // The lights are optional.
  92.     mView = ::Q3View_New();
  93.     ThrowIfNil_(mView);
  94.     MakeDrawContext();
  95.     MakeRenderer();
  96.     MakeCamera();
  97.     MakeLightGroup();
  98. }
  99.  
  100. void
  101. CQD3DPane::MakeDrawContext()
  102. {    // Make and add a draw context to the current view.
  103.     // (Perhaps we can init the TQ3DrawContextData struct from a resource.)
  104.     // (The Mac part has to be done by hand.)
  105.     TQ3DrawContextData        data;
  106.     TQ3MacDrawContextData    macData;
  107.     TQ3DrawContextObject    theContext ;
  108.     
  109.     //    Fill in draw context data.
  110.     data.clearImageMethod = kQ3ClearMethodWithColor;
  111.     GetClearImageColor(&(data.clearImageColor));
  112.     data.paneState = kQ3False;
  113.     data.maskState = kQ3False;
  114.     data.doubleBufferState = kQ3True;
  115.  
  116.     macData.drawContextData = data;
  117.     
  118.     // this is the window associated with the view
  119.     macData.window = (CGrafPtr) GetMacPort();
  120.     macData.library = kQ3Mac2DLibraryNone;
  121.     macData.viewPort = nil;
  122.     macData.grafPort = nil;
  123.     
  124.     //    Create draw context
  125.     theContext = ::Q3MacDrawContext_New(&macData) ;
  126.     ThrowIfNil_(theContext);
  127.     StQ3Disposer con(theContext);    // automatically dispose
  128.     
  129.     // Attach the draw context to our view.
  130.     TQ3Status status = ::Q3View_SetDrawContext(mView, theContext);
  131.     ThrowIfQ3Fail_(status);
  132. }
  133.  
  134. void
  135. CQD3DPane::MakeRenderer()
  136. {
  137.     TQ3RendererObject theRenderer;
  138.     TQ3Status status;
  139.     
  140.     theRenderer = ::Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
  141.     ThrowIfNil_(theRenderer);
  142.     StQ3Disposer ren(theRenderer);    // automatically dispose
  143.     
  144.     // attach to the view
  145.     status = ::Q3View_SetRenderer(mView, theRenderer);
  146.     ThrowIfQ3Fail_(status);
  147.     
  148.     // these two lines set us up to use the best possible renderer,
  149.     // including  hardware if it is installed.
  150.     ::Q3InteractiveRenderer_SetDoubleBufferBypass (theRenderer, kQ3True);                        
  151.     ::Q3InteractiveRenderer_SetPreferences(theRenderer, kQAVendor_BestChoice, 0);
  152.     
  153. }
  154.  
  155. void
  156. CQD3DPane::DrawSelf()
  157. {    // Your basic submitting loop.
  158.     TQ3Status        status;
  159.     TQ3ViewStatus    viewStatus;
  160.     status = ::Q3View_StartRendering(mView);
  161.     ThrowIfQ3Fail_(status);
  162.     try {
  163.         do {
  164.             // Don't throw anything from inside this loop, else
  165.             // ::Q3View_EndRendering() never gets called.
  166.             // (Can we fix that with a stack object?)
  167.             status = SubmitScene();
  168.             viewStatus = ::Q3View_EndRendering(mView);
  169.         } while ( viewStatus == kQ3ViewStatusRetraverse );
  170.     }
  171.     catch (...) {
  172.         // if something threw an exception, we need to stop rendering
  173.         status = ::Q3View_Cancel(mView);
  174.         throw;
  175.     }
  176.     ThrowIfQ3Any_();
  177. }
  178.  
  179. TQ3Status
  180. CQD3DPane::SubmitScene()
  181. {    // As recommended in develop 23, we separate the body 
  182.     // of the Submit loop so it may be used for other things
  183.     // than rendering.
  184.     // There is no model yet, but this code could be called from 
  185.     // a sub-class which also submits a model.
  186.     TQ3Status status;
  187.     status = ::Q3Style_Submit( mInterpolation, mView );
  188.     if (status==kQ3Failure) return status;
  189.     status = ::Q3Style_Submit( mBackFacing, mView );
  190.     if (status==kQ3Failure) return status;
  191.     status = ::Q3Style_Submit( mFillStyle, mView );
  192.     return status;
  193. }
  194.  
  195.